//-----------------------------------------------------------------------------
// Filename: SessionsState.cs
//
// Description: A state class used by assemblies involved in web applications
// to set and retrieve session information.
//
// History:
// 21 Jan 2004	Aaron Clauson	Created.
// 04 Sep 2004	Aaron Clauson	Added a new method to allow the setting of cookies
//								for in memory storage by user agents.
//
// License: 
// Public Domain.
//-----------------------------------------------------------------------------

using System;
using System.Web;

namespace MaverickLite.Config
{
	/// <summary>
	/// This class is responsible for establishing and maintaining state between 
	/// client requests. This class does not neccessarily correspond to the ASP.NET
	/// Session object. A number of alternatives may be used depending on the scenario.
	/// 
	/// Establishing and maintaining a session in a browser/web server system can be
	/// more difficult then expected. A non-exhaustive list of things that can go
	/// wrong and hence to be aware of are:
	/// 
	/// When using cookies, either explicitly or using the ASP Session object,
	/// 
	/// 1. Browser could have disabled cookies,
	/// 
	/// 2. Some firewalls, especially personal ones, will strip out certain HTTP headers
	///    from browser requests, the cookie headers could become a casualty here,
	///    
	/// 3. A more obscure problem is domain cloaking or redirecting. Domain registrars, 
	///    as well as registering your domain, will host the DNS entry for you. When your
	///    web site is set up instead of moving your DNS entry the registrar can place a 
	///    bit of client side html/script to redirect all your requests to the new site.
	///    In most cases this will break cookies since the registrar's web server and your
	///    web site host server are likely to be in different domains and cookies are set 
	///    and sent based on the server domain.  The way around this is to obviously get the
	///    DNS entry to point directly to the web server: unfortunately this usually costs $$.
	///     An exmaple of domain cloaking client side html is:
	///     
	///    <html>
	///			<frameset rows='0,*' border='0' frameborder='0'>
	///			<frame name='a' noresize>
	///			<frame name='b' src='http://a.differentdomain.com/'>
	///		</html>
	///		
	///    If domain cloaking is not used, meaning the browser will be redirected
	///    to the correct site; the address bar url will change to the new url whereas with 
	///    domain cloaking it will not; the problem is also alleviated. An example of non
	///    cloaking client side javascript is:
	///    
	///    <script>
	///		   window.location = 'http://a.differentdomain.com'; // In this case the address bar will change and cookies will work.
	///    </script>
    ///		    
	///    And after just spending five minutes looking for the above example there are a
	///    a whole plethora of client side techniques that can break cookies/HTTP headers
	///    every which way. That being said cookies can be very handy as a state persitence
	///    technique, see below. 
	///    
	///    If something needs to be protected on a web site a strong authentication method
	///    over SSL (https) is the best option.
	///    
	/// When using a query string parameter to maintain state,
	/// 
	/// 1. Major pain to place a query string parameter in every link on the site.
	/// 
	/// When using a form parameter to maintain state,
	/// 
	/// 1. Results in an annoying prompt to resend form data in browsers when refreshing pages,
	/// 2. Links within the site often are GETs not POSTs so form parameters won't be sent
	///    with requests.
	///    
	/// Best solution: Cookies. 
	///    If cookies are essential provide error messages if the HTTP cookie headers are not
	///    getting through.
	///    
	/// In a nutshell web apps are meant to be stateful; the web has become one big hack ;-).
	/// </summary>
	public class SessionState
	{
		private HttpContext m_inContext;	// Holds a reference to the current HTTP context.

		public SessionState(HttpContext inContext)
		{
			this.m_inContext = inContext;
		}

		/// <summary>
		/// Requests the browser of user agent to store a cookie in the client memory. Typically
		/// this will result in the cookie persisting for the duration of the browser or user
		/// agent's session. 
		/// </summary>
		public void SetSessionValue(string key, object keyValue)
		{
			this.m_inContext.Response.Cookies[key].Value = (string)keyValue;
		}

		/// <summary>
		/// Requests the brower or user agent to set a persistnet cookie on the client. Typically
		/// the cookie will be saved onto the hard drive.
		/// </summary>
		public void SetSessionValue(string key, object keyValue, DateTime expirationTime)
		{
			this.m_inContext.Response.Cookies[key].Value = (string)keyValue;
			this.m_inContext.Response.Cookies[key].Expires = expirationTime;
		}

	}
}
